#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#include "slip.h"

// Configure Serial2 for ESP32-S3: TX=GPIO13, RX=GPIO14
HardwareSerial MySerial(2);
SlipStream slip(MySerial);

// This code has been tested and verified on the `PyDuinoespESP32C3` development board.

constexpr uint8_t LED_PIN = 10;
constexpr uint16_t LED_COUNT = 1;
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(115200); // USB CDC for debug/info
  while (!Serial) {}

  MySerial.setRxBufferSize(512);
  MySerial.setTxBufferSize(512);
  MySerial.begin(115200, SERIAL_8N1, 14, 13); // RX=14, TX=13
  Serial.println("ESP32-S3 SLIP demo started. Using Serial2 for SLIP frames.");

  strip.begin();
  strip.setBrightness(64);
  strip.clear();
  strip.show();
}

void loop() {
  static int index = 0;
  static size_t colorIndex = 0;
  static unsigned long lastSendMs = 0;
  static unsigned long lastStatusMs = 0;
  constexpr unsigned long sendIntervalMs = 1000;

  const unsigned long now = millis();

  if (now - lastSendMs >= sendIntervalMs) {
    char jsonMsg[1024];
    snprintf(jsonMsg, sizeof(jsonMsg), "{\"loopnum\":%d}", index);
    slip.send((const uint8_t *)jsonMsg, strlen(jsonMsg));
    Serial.print("Sent SLIP frame: ");
    Serial.println(jsonMsg);
    index++;
    lastSendMs = now;
  }

  // Immediately poll and try to receive what was sent (self-test)
  slip.poll();
  if (slip.has_frame()) {
    uint8_t buffer[1024];
    size_t length = 0;
    if (slip.recv(buffer, length)) {
      Serial.print("Received SLIP frame: ");
      Serial.write(buffer, length);
      Serial.println();

      static const uint8_t colors[][3] = {
          {255, 0, 0},
          {0, 255, 0},
          {0, 0, 255},
      };
      const auto &rgb = colors[colorIndex];
      strip.setPixelColor(0, strip.Color(rgb[0], rgb[1], rgb[2]));
      strip.show();
      colorIndex = (colorIndex + 1) % (sizeof(colors) / sizeof(colors[0]));
    }
  } else {
    if (now - lastStatusMs >= 1000) {
      Serial.println("Waiting for complete SLIP frame...");
      lastStatusMs = now;
    }
  }
}